import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.Key;

public class Server {
    public static void main(String args[]) {
        MyDC mydc = new MyDC();
        ServerSocket serverForClient = null;
        Socket socketOnServer = null;
        DataOutputStream out = null;
        DataInputStream in = null;
        try {
            serverForClient = new ServerSocket(2010);
        } catch (IOException e1) {
            System.out.println(e1);
        }
        try {
            System.out.println("watting for client");
            socketOnServer = serverForClient.accept(); //堵塞状态，除非有客户呼叫
            System.out.println("Connected");
            out = new DataOutputStream(socketOnServer.getOutputStream());
            in = new DataInputStream(socketOnServer.getInputStream());

            Key_DH.DH("Spub.dat","Spri.dat");
            int len = Integer.parseInt(in.readUTF());
            byte np[] = new byte[len];
            for (int i = 0;i<len;i++) {
                String temp = in.readUTF();
                np[i] = Byte.parseByte(temp);
            }
            ObjectInputStream ois = new ObjectInputStream (new ByteArrayInputStream (np));
            Key k2 = (Key)ois.readObject();;
            FileOutputStream f2 = new FileOutputStream("Cpub.dat");
            ObjectOutputStream b2 = new ObjectOutputStream(f2);
            b2.writeObject(k2);

            FileInputStream fp = new FileInputStream("Spub.dat");
            ObjectInputStream bp = new ObjectInputStream(fp);
            Key kp = (Key) bp.readObject();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(kp);
            byte[] kb = baos.toByteArray();
            out.writeUTF(kb.length + "");
            for (int i = 0; i < kb.length; i++) {
                out.writeUTF(kb[i] + "");
            }

            KeyAgree.DH("Cpub.dat","Spri.dat");

            String leng = in.readUTF(); // in读取信息，堵塞状态
            byte ctext[] = new byte[Integer.parseInt(leng)];
            for (int i = 0;i<Integer.parseInt(leng);i++) {
                String temp = in.readUTF();
                ctext[i] = Byte.parseByte(temp);
            }
            // 获取密钥
            FileInputStream f = new FileInputStream("sb.dat");
            byte[] keysb = new byte[24];
            f.read(keysb);
            System.out.println("公共密钥：");
            for (int i = 0;i<24;i++) {
                System.out.print(keysb[i]+",");
            }
            System.out.println("");
            SecretKeySpec k = new SecretKeySpec(keysb, "DESede");
            // 解密
            Cipher cp = Cipher.getInstance("DESede");
            cp.init(Cipher.DECRYPT_MODE, k);
            byte[] ptext = cp.doFinal(ctext);
            System.out.println("");
            // 显示明文
            String p = new String(ptext,"UTF8");
            System.out.println("解密后信息:" + p);
            out.writeUTF(mydc.evaluate(p)+"");
        } catch (Exception e) {
            System.out.println("Server is already stoped" + e);
        }
    }
}